package cn.hsw.platform.core.exception;

import cn.hsw.platform.core.base.BaseConstant;
import cn.hsw.platform.core.dto.ResultDto;
import cn.hsw.platform.core.enums.HttpEnum;
import cn.hsw.platform.core.util.ResultUtil;
import cn.hsw.platform.core.util.Validator;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * Rest请求全局异常拦截
 * @author 李子木
 * @date 2020-10-23
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private final Log log = LogFactory.get("****全局异常捕捉****");


    /**
     * 系统内部异常捕捉
     * @param e 异常
     * @return rest返回500错误
     */
    @ExceptionHandler(Exception.class)
    public ResultDto<Object> handleException(Exception e){

        log.error(BaseConstant.PLATFORM_ERROR_TAG+":{}",e.fillInStackTrace());

        String msg = e.getMessage();

        return handleException(BaseConstant.PLATFORM_ERROR_TAG,HttpEnum.ERROR.getCode(), Validator.isNotEmpty(msg)?msg:HttpEnum.ERROR.getMsg());

    }

    /**
     * 参数校验异常捕捉
     * @param e 异常
     * @return rest返回400参数校验错误
     */
    @ExceptionHandler({BindException.class})
    public ResultDto<Object> handleException(BindException e){

        return checkParamHandleException(e.getAllErrors().get(0).getDefaultMessage());
    }

    /**
     * 参数校验异常捕捉
     * @param e 异常
     * @return rest返回400参数校验错误
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ResultDto<Object> handleException(MissingServletRequestParameterException e){

        return checkParamHandleException(e.getMessage());
    }



    /**
     * 参数校验异常捕捉
     * @param e 异常
     * @return rest返回400参数校验错误
     */
    @ExceptionHandler(ValidateException.class)
    public ResultDto<Object> handleException(ValidateException e){

        return checkParamHandleException(e.getMessage());
    }

    private ResultDto<Object> checkParamHandleException(String msg){

        return handleException(BaseConstant.CHECK_PARAM_ERROR_TAG,HttpEnum.BAD_REQUEST.getCode(), Validator.isNotEmpty(msg)?msg:HttpEnum.BAD_REQUEST.getMsg());
    }

    private ResultDto<Object> handleException(String tag,Integer code,String msg){

        log.warn(tag+":{}",msg);

        return ResultUtil.error(code,msg);
    }

    //@TODO 参数校验异常、权限认证异常
}
